package com.bsj.power.pls.config.net.netty;

import com.bsj.power.pls.config.net.netty.common.client.HandleClientRTK;
import com.bsj.power.pls.config.net.netty.common.client.RTKDecode;
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import lombok.extern.slf4j.Slf4j;

import java.net.InetSocketAddress;
import java.util.concurrent.TimeUnit;

/**
 * @author yinhao
 * @version 1.0
 * @description tcp客户端
 * @date 2024/10/12
 */
@Slf4j
public class TcpClientNet {
    private String host;
    private int port;
    private static Bootstrap bootstrap;
    private static NioEventLoopGroup group;
    private static ChannelFuture future;
    private static ChannelFutureListener channelFutureListener = null;

    public TcpClientNet(String host, int port) {
        this.host = host;
        this.port = port;
    }

    // 初始化客户端
    public void initClient() {
        group = new NioEventLoopGroup();

        // Client服务启动器 3.x的ClientBootstrap
        // 改为Bootstrap，且构造函数变化很大，这里用无参构造。
        bootstrap = new Bootstrap();
        // 指定EventLoopGroup
        bootstrap.group(group);
        // 指定channel类型
        bootstrap.channel(NioSocketChannel.class);
        // 指定Handler
        bootstrap.handler(new ChannelInitializer<SocketChannel>() {
            @Override
            protected void initChannel(SocketChannel ch) throws Exception {
                ch.pipeline().addLast(new RTKDecode());
                ch.pipeline().addLast(new HandleClientRTK());
            }
        });
        //设置TCP协议的属性
        bootstrap.option(ChannelOption.SO_KEEPALIVE, true);
        bootstrap.option(ChannelOption.TCP_NODELAY, true);
        bootstrap.option(ChannelOption.SO_TIMEOUT, 5000);

        channelFutureListener = new ChannelFutureListener() {
            @Override
            public void operationComplete(ChannelFuture f) throws Exception {

                if (f.isSuccess()) {
                    log.info("重新连接服务器成功");

                } else {
                    log.info("重新连接服务器失败");
                    //  3秒后重新连接
                    f.channel().eventLoop().schedule(new Runnable() {
                        @Override
                        public void run() {
                            doConnect();
                        }
                    }, 3, TimeUnit.SECONDS);
                }
            }
        };

    }

    /**
     * 连接到服务端
     */
    public void doConnect() {
        log.info("doConnect");
//        ChannelFuture future = null;
        try {
            future = bootstrap.connect(new InetSocketAddress(
                    host, port));
            future.addListener(channelFutureListener);

        } catch (Exception e) {
            e.printStackTrace();
            //future.addListener(channelFutureListener);
            log.info("关闭连接");
        }
    }

    /**
     * 关闭
     */
    public void stop() {
        if (future != null) {
            Channel channel = future.channel();
            channel.close();
        }
        group.shutdownGracefully();
        log.info("RTK TCP客户端关闭");
    }

}
